/**
 * @Date 2025/1/6 9:09
 * @Created by 衡盛永
 */

package org.example.deploy.controller;

import org.example.deploy.common.MyUserDetails;
import org.example.deploy.dto.ResultDto;
import org.example.deploy.pojo.SysUser;
import org.example.deploy.service.SysUserService;
import org.example.deploy.utils.RedisUtil;
import org.example.deploy.utils.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping("/api")
public class SecurityLoginController {
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private AuthenticationManager authenticationManagerBean;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RedisUtil redisUtil;

    @PostMapping("register")
    public String register(@RequestParam String username, @RequestParam String password) {
        SysUser user = new SysUser();
        // 调用加密器将前端传递过来的密码进行加密
        user.setUsername(username);
        user.setPassword(passwordEncoder.encode(password));
        // 将用户实体对象添加到数据库@PreAuthorize("hasAuthority('test')")
        sysUserService.save(user);
        return "注册成功";
    }

    @PostMapping("login")
    public ResultDto<Map<String, Object>> login(@RequestBody SysUser sysUser) {
        // 将表单数据封装到 UsernamePasswordAuthenticationToken
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(sysUser.getUsername(), sysUser.getPassword());
        // AuthenticationManager校验这个认证信息，返回一个已认证的Authentication
        Authentication authentication = authenticationManagerBean.authenticate(usernamePasswordAuthenticationToken);
        if (Objects.isNull(authentication)) {
            throw new RuntimeException("用户名或密码错误");
        }
        // 将返回的Authentication存到上下文中
        SecurityContextHolder.getContext().setAuthentication(authentication);
        // 校验成功，强转对象
        MyUserDetails loginUser = (MyUserDetails) authentication.getPrincipal();
        SysUser sysUser1 = loginUser.getSysUser();
        String userId = sysUser1.getId().toString();
        // 校验通过返回token
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("userId", userId);
        //authenticate存入redis
        redisUtil.setCacheObject("login:" + userId, loginUser);
        String token = TokenUtil.sign(hashMap);
        // SG 生成token
//        String token = JwtUtil.createJWT(sysUser1.getId().toString());
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        map.put("username", sysUser.getUsername());
        return ResultDto.success("登录成功", map);
    }
}
